// import axios from './axios'
import { request as axios } from '@monkey.do/monkey';
var qs = require('qs');

// import router from '../router';
// import _pick from 'lodash/pick'
import _assign from 'lodash/assign';
import _isEmpty from 'lodash/isEmpty';

import {
  assert,
} from '@/utils';
import {
  API_DEFAULT_CONFIG,
} from '@/config';
import API_CONFIG from '@/service/api';

class MakeApi {
  constructor(options) {
    this.api = {};
    this.apiBuilder(options);
  }

  apiBuilder({
    namespaces = [],
    sep = '|',
    level = 0,
    apis = {},
    mock = false,
    debug = false,
    mockBaseURL = '',
  }) {
    Object.keys(apis).map(namespace => {
      var childrenApis = apis[namespace];
      if (childrenApis instanceof Array) {
        this._apiSingleBuilder({
          namespaces,
          namespace,
          mock,
          mockBaseURL,
          sep,
          debug,
          apis: childrenApis,
        });
      } else {
        if (level === 0) {
          namespaces = [];
        }
        namespaces.push(namespace);
        this.apiBuilder({
          namespaces,
          sep,
          level: 1,
          apis: childrenApis,
          mock,
          debug,
          mockBaseURL,
        });
      }
      return namespace;
    });
  }

  _apiSingleBuilder({
    namespaces = [],
    namespace,
    sep = '|',
    apis = {},
    mock = false,
    debug = false,
    // mockBaseURL = ''
  }) {
    apis.forEach(api => {
      const {
        name,
        desc,
        params,
        method,
        server,
        path,
        responseType,
        mockPath,
      } = api;
      const ns = namespaces.join(sep);
      // debugger
      // const apiUrl = name === 'CmdiLogin' || name === 'Login' || name === 'Info' || name === 'Captchas' || name === 'CaptchasImg' || name === 'CodeVerification' ? `${namespace}${sep}${name}` : `${ns}${sep}${namespace}${sep}${name}`
      const apiUrl = `${ns}${sep}${namespace}${sep}${name}`;
      // let apiUrl = ns ? `${ns}${sep}${namespace}${sep}${name}` : `${namespace}${sep}${name}`,
      const url = (mock || api.mock === undefined || api.mock) ? path : mockPath;

      // url = mock && api.mock ? mockPath : path,
      // const baseURL = (mock || api.mock === undefined || api.mock) ? process.env.VUE_APP_BASE_API : api.baseURL || (server ? GLOBAL[server] : GLOBAL.BASE_SERVER);
      // eslint-disable-next-line
      const baseURL = (server ? GLOBAL[server] : GLOBAL.BASE_SERVER);

      debug && assert(name, `${apiUrl} :接口name属性不能为空`);
      debug && assert(apiUrl.indexOf('/') === 0, `${apiUrl} :接口路径path，首字符不应为/`);

      Object.defineProperty(this.api, apiUrl, {
        value(outerParams, outerOptions) {
          var paramJson = null;
          if (outerParams) {
            paramJson = JSON.parse(JSON.stringify(outerParams));
          }
          // 替换地址中的{}中的参数
          var realUrl = url;
          if (outerParams && url.indexOf('{') !== -1) {
            for (var key in outerParams) {
              if (realUrl.indexOf('{' + key + '}') !== -1) {
                realUrl = realUrl.replace('{' + key + '}', outerParams[key]);
                delete paramJson[key];
              }
            }
          }
          // _pick(_assign({}, params, outerParams), Object.keys(params))
          const _data = _isEmpty(paramJson) ? params : _assign({}, params, paramJson);
          if (realUrl.indexOf('{projectId}') !== -1) {
            const projectId = router.currentRoute.params['id'];
            realUrl = realUrl.replace('{projectId}', projectId);
          }
          return axios(_normoalize(_assign({
            url: realUrl,
            desc,
            baseURL,
            responseType: responseType || 'json',
            method,
          }, outerOptions), _data));
        },
      });
    });
  }
}

function _normoalize(options, data) {
  if (options.method === 'POST') {
    options.data = data;
  } else if (options.method === 'GET') {
    options.paramsSerializer = function(params) {
      return qs.stringify(params, { arrayFormat: 'repeat' });
    };
    options.params = data;
  } else if (options.method === 'PUT') {
    options.data = data;
  } else if (options.method === 'DELETE') {
    options.params = data;
    options.paramsSerializer = function(params) {
      return qs.stringify(params, { arrayFormat: 'repeat' });
    };
  }
  return options;
}

export default new MakeApi({
  apis: API_CONFIG,
  ...API_DEFAULT_CONFIG,
})['api'];
